package net.dotool;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

/**
 * @author 李岩飞
 * @email eliyanfei@126.com	
 * 2018年3月7日 下午1:52:39
 * 
 */
public class ImageTools {

	/**
	 * 将图片转换成Base64编码
	 * @param imgFile 待处理图片
	 * @return
	 */
	public static String imageToData(String imgFile) {
		//将图片文件转化为字节数组字符串，并对其进行Base64编码处理
		InputStream in = null;
		byte[] data = null;
		//读取图片字节数组
		try {
			in = new FileInputStream(imgFile);
			data = new byte[in.available()];
			in.read(data);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return Base64.encodeToString(data, true);
	}

	/**
	 * 对字节数组字符串进行Base64解码并生成图片
	 * @param imageData 图片数据
	 * @param filePath 保存图片全路径地址
	 * @return
	 */
	public static boolean dataToImage(String imageData, String filePath) {
		//
		if (imageData == null) //图像数据为空
			return false;
		try {
			//Base64解码
			byte[] b = Base64.decode(imageData);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {//调整异常数据
					b[i] += 256;
				}
			}
			//生成jpeg图片
			OutputStream out = new FileOutputStream(filePath);
			out.write(b);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 缩放图片方法
	 * @param srcFile 要缩放的图片路径
	 * @param destFile 缩放后的图片路径
	 * @param height 目标高度像素
	 * @param width  目标宽度像素  
	 * @param filterWhite     是否补白
	 */
	public final static void scale(String srcFile, String destFile, int height, int width, boolean filterWhite) {
		try {
			double ratio = 0.0; // 缩放比例
			File f = new File(srcFile);
			BufferedImage bi = ImageIO.read(f);
			Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);//bi.SCALE_SMOOTH  选择图像平滑度比缩放速度具有更高优先级的图像缩放算法。
			// 计算比例
			if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
				double ratioHeight = (new Integer(height)).doubleValue() / bi.getHeight();
				double ratioWhidth = (new Integer(width)).doubleValue() / bi.getWidth();
				if (ratioHeight > ratioWhidth) {
					ratio = ratioHeight;
				} else {
					ratio = ratioWhidth;
				}
				AffineTransformOp op = new AffineTransformOp(AffineTransform//仿射转换
						.getScaleInstance(ratio, ratio), null);//返回表示剪切变换的变换
				itemp = op.filter(bi, null);//转换源 BufferedImage 并将结果存储在目标 BufferedImage 中。
			}
			if (filterWhite) {//补白
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//构造一个类型为预定义图像类型之一的 BufferedImage。
				Graphics2D g = image.createGraphics();//创建一个 Graphics2D，可以将它绘制到此 BufferedImage 中。
				g.setColor(Color.white);//控制颜色
				g.fillRect(0, 0, width, height);// 使用 Graphics2D 上下文的设置，填充 Shape 的内部区域。
				if (width == itemp.getWidth(null))
					g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
				else
					g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
				g.dispose();
				itemp = image;
			}
			ImageIO.write((BufferedImage) itemp, "JPEG", new File(destFile)); //输出压缩图片
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 传入文件
	 * @param file
	 * @throws Exception
	 */
	public static BufferedImage grayImage(File file) throws Exception {
		return grayImage(ImageIO.read(file));
	}

	/**
	 * @param bufferedImage 待处理图片
	 */
	public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {
		int width = bufferedImage.getWidth();
		int height = bufferedImage.getHeight();
		BufferedImage grayBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				// 计算灰度值
				final int color = bufferedImage.getRGB(x, y);
				final int r = (color >> 16) & 0xff;
				final int g = (color >> 8) & 0xff;
				final int b = color & 0xff;
				int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b);
				int newPixel = colorToRGB(255, gray, gray, gray);
				grayBufferedImage.setRGB(x, y, newPixel);
			}
		}
		return grayBufferedImage;
	}

	/**
	 * 颜色分量转换为RGB值
	 * @param alpha
	 * @param red
	 * @param green
	 * @param blue
	 * @return
	 */
	private static int colorToRGB(int alpha, int red, int green, int blue) {
		int newPixel = 0;
		newPixel += alpha;
		newPixel = newPixel << 8;
		newPixel += red;
		newPixel = newPixel << 8;
		newPixel += green;
		newPixel = newPixel << 8;
		newPixel += blue;
		return newPixel;
	}
}
